package com.atguigu.proxy.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class DynamicProxyLog<T> {

    // 被代理的目标对象
    private T target;

    public DynamicProxyLog(T target) {
        this.target = target;
    }

    // 创建代理对象（动态代理：JDK自带技术，不需要额外导入 jar 包）
    public <T> T newProxyInstance() {

        // 获取类加载器对象
        ClassLoader classLoader = DynamicProxyLog.class.getClassLoader();

        // 被代理的目标类实现了哪些接口
        Class<?>[] interfaces = target.getClass().getInterfaces();

        // 封装所有代理逻辑
        // proxy 参数：代理对象
        // method 参数：被代理的目标对象方法
        // args 参数：被代理的目标对象方法的参数
        InvocationHandler handler = (Object proxy, Method method, Object[] args) -> {

            try {
                // 核心操作前：打印日志说目标方法开始了
                System.out.println("[非核心业务]" + method.getName() + "方法开始了，入参列表是：" + ((args == null || args.length == 0) ? "[]" : Arrays.asList(args)));

                // 核心操作：调用目标对象的方法
                method.setAccessible(true);
                Object invokeResult = method.invoke(target, args);

                // 核心操作成功之后：打印日志说目标方法成功了
                System.out.println("[非核心业务]" + method.getName() + "方法成功结束了，返回值是：" + invokeResult);

                return invokeResult;
            } catch (Exception e) {
                // 核心操作抛出异常之后：打印日志说目标方法抛异常了
                System.out.println("[非核心业务]" + method.getName() + "方法因为抛异常结束了，异常类型是：" + e.getClass().getName());

                throw new RuntimeException(e);
            } finally {
                // 核心操作最终结束：打印日志说目标方法结束了
                System.out.println("[非核心业务]" + method.getName() + "方法最终结束了");
            }
        };

        // 创建代理对象
        return (T) Proxy.newProxyInstance(classLoader, interfaces, handler);
    }
}
